import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:example_example/pages/person/Login.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

//import '../mainP29_02_BottomNavigationBar.dart';
import 'ToastUtils.dart';
import 'Storage.dart';

import '../util/LogUtil.dart';

/**
 *  https://www.cnblogs.com/gxsyj/p/11162011.html
 * */
class BaseUrl {
  // 配置默认请求地址
//  static const String url = 'https://test90.cebserv.com/';
}

class HttpUtil {
  static BuildContext mContext;

  static void get(String url,
      {BuildContext context,
      Map<String, dynamic> data,
      Map<String, dynamic> headers,
      Function success,
      Function error}) async {
    if (context != null) {
      mContext = context;
    }

    // 数据拼接
    if (data != null && data.isNotEmpty) {
      StringBuffer options = new StringBuffer('?');
      data.forEach((key, value) {
        options.write('${key}=${value}&');
//        print("参数key:$key");
//        print("参数value:$value");
      });
      String optionsStr = options.toString();
      optionsStr = optionsStr.substring(0, optionsStr.length - 1);
      url += optionsStr;
    }

    // 发送get请求
    await _sendRequest(url, 'get', success, headers: headers, error: error);
  }

  static void post(String url,
      {BuildContext context,
      Map<String, dynamic> data,
      Map<String, dynamic> headers,
      Function success,
      Function error}) async {
    if (context != null) {
      mContext = context;
    }
    // 发送post请求
    _sendRequest(url, 'post', success,
        data: data, headers: headers, error: error);
  }

  static void delete(String url,
      {BuildContext context,
      Map<String, dynamic> data,
      Map<String, dynamic> headers,
      Function success,
      Function error}) async {
    if (context != null) {
      mContext = context;
    }
    // 发送post请求
    _sendRequest(url, 'delete', success,
        data: data, headers: headers, error: error);
  }

  // 请求处理
  static Future _sendRequest(String url, String method, Function success,
      {Map<String, dynamic> data,
      Map<String, dynamic> headers,
      Function error}) async {
//    String _code;
    String _msg;
//    var _backData;

    // 检测请求地址是否是完整地址
    if (!url.startsWith('http')) {
//      url = BaseUrl.url + url;
    }

    print("工具类url:$url");

    try {
      Map<String, dynamic> dataMap = data == null ? new Map() : data;
      Map<String, dynamic> headersMap = headers == null ? new Map() : headers;
      print("工具类..." + dataMap.length.toString());

      dataMap.forEach((mykey, myvalue) {
//        print("--key, value--${mykey} ${myvalue}");
        LogUtil.v("--key: ${mykey} value: ${myvalue}");
      });

      // 配置dio请求信息
      Response response;
      Dio dio = new Dio();
      dio.options.connectTimeout = 10000; // 服务器链接超时，毫秒
      dio.options.receiveTimeout = 3000 * 10; // 响应流上前后两次接受到数据的间隔，毫秒
      dio.options.headers
          .addAll(headersMap); // 添加headers,如需设置统一的headers信息也可在此添加

      if (method == 'get') {
        response = await dio.get(url);
      } else if (method == "post") {
        response = await dio.post(url, data: dataMap);
      } else {
        response = await dio.delete(url, data: dataMap);
      }
      LogUtil.init(title: "来自LogUtil", isDebug: false, limitLength: 800);
      LogUtil.v("接口的数据：${response.data}");

//    接口的数据：{code: 401, success: false, data: null, msg: 用户登录超时}
//         接口的数据response.statusCode：200
      /**
       *  注意：登录一段时间后，再打开app后；如果登录超时了，那么就会返回上面的数据，但是
       *  response.statusCode获取的却依然是200，此时就无法走到工具类里面的401，需要在各个接口中去判断吗？
       *  如：MyNeedDoPage类 和 WaitAllPage类
       *  再次解析返回的code是否是200，然后再做处理
       */

      if (success != null) {
        LogUtil.v("接口的数据response.statusCode：${response.statusCode}");
        if (response.statusCode == 200) {
//          success(_backData);
          var code = response.data["code"];
          var msg = response.data["msg"];
          print("工具类的...msg:$msg");
          print("工具类的...code:$code");

          // code==200 code=="200" 都不可靠
          if (code != null && code.toString() == "200") {
            print("是否进来了啊daa");
            success(response.data);
          } else if (code != null && code.toString() == "401") {
            print("工具类的...401。。false。。");
            ToastUtils.toast("请重新登录");
            Storage.clear(); // 删除缓存
//            Navigator.pushNamed(mContext, '/login');
            if (mContext != null) {
              print("工具类的...401的要退出的哦。。");
              Navigator.pushAndRemoveUntil(
                mContext,
                new MaterialPageRoute(builder: (context) => new LoginPage()),
                (route) => route == null,
              );
            }
          } else {
            print("报错了啊");
            if (msg != null) {
              ToastUtils.toast(msg);
            }
          }

//          if (success != null && success == true) {
//            success(response.data);
//          }else{
//            print("工具类的...401。。false。。");
//            ToastUtils.toast("请重新登录");
//            Storage.clear(); // 删除缓存
//             Navigator.pushAndRemoveUntil(
//               mContext,
//               new MaterialPageRoute(builder: (context) => new LoginPage()),
//                   (route) => route == null,
//             );
//          }
        } else if (response.statusCode == 401) {
          print("工具类...401。。。。退出登录吧");
          ToastUtils.toast("请重新登录");
          Storage.clear(); // 删除缓存
          if (mContext != null) {
            print("工具类...401。去退出了");
            Navigator.pushAndRemoveUntil(
              mContext,
              new MaterialPageRoute(builder: (context) => new LoginPage()),
              (route) => route == null,
            );
          }
        } else {
          print("错误11111");
          _msg = '网络请求错误,状态码:' + response.statusCode.toString();
          _handError(error, _msg);
        }
      } else {
        print("错误2222");
        _msg = 'else网络请求错误,状态码:' + response.statusCode.toString();
        _handError(error, _msg);
      }

//      if(response.statusCode != 200){
//        _msg = '网络请求错误,状态码:' + response.statusCode.toString();
//        _handError(error, _msg);
//        return;
//      }

      // 返回结果处理
//      Map<String, dynamic> resCallbackMap = response.data;
//      _code = resCallbackMap['code'];
//      _msg = resCallbackMap['msg'];
//      _backData = resCallbackMap['data'];

//      print("工具类..._code $_code");
//      print("工具类..._msg $_msg");
//      print("工具类..._backData $_backData");

    } catch (exception) {
      print("工具类啊数据请求错误${exception.toString()}");
      _handError(error, '数据请求错误：' + exception.toString());

      if (exception.toString().contains("401")) {
        print("工具类... 401。。。。catch");
        ToastUtils.toast("请重新登录");
        Storage.clear(); // 删除缓存
//        Storage.clear();
        if (mContext != null) {
//          Navigator.pushNamed(mContext, '/login');
          print("工具类...401。去退出了aaa");
          Navigator.pushAndRemoveUntil(
            mContext,
            new MaterialPageRoute(builder: (context) => new LoginPage()),
            (route) => route == null,
          );
          //跳转并关闭当前页面
//          Navigator.pushAndRemoveUntil(
//            mContext,
//            new MaterialPageRoute(builder: (mContext) => Tabs()),  // LoginPage
//                (route) => route == null,
//          );
        }
      } else {
        ToastUtils.toast("数据请求错误");
      }
    }
  }

  // 返回错误信息
  static Future _handError(Function errorCallback, String errorMsg) {
//    {"code":"401","success":false,"data":null,"msg":"用户登录超时"}
//    var bean = json.decode(errorMsg); // Json 字符串转化成 Map 类型
//    String msg= bean["msg"];
//    if(msg!=null){
//      ToastUtils.toast("msg");
//    }
    print("错误3333 _handError");
    print("错误3333 _handError$errorMsg");
    if (errorMsg != null &&
        errorMsg.contains("was called on null")) {
      print("错误4444 这个错误如何导致的呢");
    } else {
      ToastUtils.toast("数据请求错误");
    }

    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
  }
}
